package com.crc.luojian.method;

import com.crc.luojian.annotation.RequestBody;
import com.crc.luojian.annotation.ResponseBody;
import com.crc.luojian.resolver.RequestResolver;
import com.crc.luojian.resolver.impl.HttpServletRequestResolver;
import com.crc.luojian.resolver.impl.RequestBodyResolver;
import com.crc.luojian.resolver.impl.RequestParamResolver;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.HashSet;
import java.util.Set;

/**
 * @program: luojian-springframework
 * @description: 请求处理
 * @author: luojian58
 * @create: 2021-06-10 18:20
 */
public class MethodHanderAdapter {
    private Set<RequestResolver> requestResolvers = new HashSet<>();

    public static final String REDIRECT_URL_PREFIX = "redirect:";
    //初始化所有请求解析器
    public MethodHanderAdapter(){
        requestResolvers.add(new HttpServletRequestResolver());
        requestResolvers.add(new RequestBodyResolver());
        requestResolvers.add(new RequestParamResolver());
    }
    //处理请求
    public void handler(HttpServletRequest req, HttpServletResponse resp, MethodHandler methodHandler) throws Exception {
        //1: 校验参数是否符合
        Method method = methodHandler.getMethod();
        Parameter[] parameters = method.getParameters();

        Object[] args = new Object[parameters.length];
        int i=0;
        for (Parameter parameter : parameters){
            boolean isSuport = false;

            for(RequestResolver requestResolver : requestResolvers){
                if(requestResolver.support(parameter)){
                    isSuport = true;
                    args[i] = requestResolver.resolveArgument(req,parameter);
                }
            }
            if(!isSuport){
                throw new RuntimeException("无法解析请求: "+req.getMethod());
            }
            i++;
        }




        //2 通过反射调用方法得到返回值
        String result = (String) method.invoke(methodHandler.getBean(), args);
        //3 输出返回值
        //如果有requestBody 注解 返回json
        if(method.getAnnotation(ResponseBody.class) != null){
            resp.setContentType("text/html;charset=UTF-8");
            resp.getWriter().print(result);
            return;
        }
        else {
            if (result.startsWith(REDIRECT_URL_PREFIX)) {
                resp.sendRedirect(result.substring(REDIRECT_URL_PREFIX.length()));
                return;
            }
            RequestDispatcher requestDispatcher = req.getRequestDispatcher(result);
            requestDispatcher.forward(req, resp);
            return;
        }


    }
}
